#ifndef LOGGER_H
#define LOGGER_H


#include <QtCore>
#include <QDebug>
#include <QSharedPointer>

#include <defs/export.h>
#include <defs/global.h>

namespace Opl { namespace Core {

        /*!
          Exception while logging/initialize Logger class
          \sa Logger
          \sa LoggerItem
          */
        class CORE_EXPORT LoggerException
        {
        public:
            LoggerException(const QString& reason):what(reason){}
            QString What() { return what; }
        private:
            QString what;
        };

        /*!
          Logger item object for logging into Logger singleton class
          \sa Logger
          */
        class CORE_EXPORT LoggerItem: public QObject, public QDebug
        {
            Q_OBJECT

        public:
            enum Level
            {
                NONE    = 0,
                FATAL	= 1,
                ERR		= 2,
                WARNING = 3,
                INFO	= 4,
                DEBUG	= 5,
                TRACE	= 6
            };

            LoggerItem();
            ~LoggerItem();

            LoggerItem& Trace(const QString& message = QString());
            LoggerItem& Debug(const QString& message = QString());
            LoggerItem& Info(const QString& message = QString());
            LoggerItem& Warning(const QString& message = QString());
            LoggerItem& Error(const QString& message = QString());
            LoggerItem& Fatal(const QString& message = QString());

        private:
            void addIfNotEmpty(const QString& message);
            Q_DISABLE_COPY(LoggerItem)
            QString buffer;
            Level level;
            friend class Logger;
        };




        O_PRIVATE_DECLARE(Logger);
        class CORE_EXPORT Logger : public QObject {
            Q_OBJECT
        public:
            typedef QSharedPointer<Logger> LoggerPtr;
            enum Mode
            {
                append = QFile::Append,
                truncate = QFile::Truncate
            };

            Logger(const QString& filename, LoggerItem::Level level = LoggerItem::NONE, Mode mode = append);
            ~Logger();

            static void Initialize();
            static void Initialize(const QString& filename, const QString& level = "INFO", const QString& mode = "APPEND");
            static void Initialize(const QString& filename, LoggerItem::Level level = LoggerItem::INFO, Mode mode = append);
            static LoggerPtr logger();
            void LogMessage(const LoggerItem& msg);

        signals:
                void message(LoggerItem::Level level, QString msg);
        private:
            static LoggerPtr _loggerPtr;

            Q_DISABLE_COPY(Logger)
            O_PRIVATE_DECLARE_MEMBER(Logger)
        };





}}

#define LI Opl::Core::LoggerItem()

#endif // LOGGER_H

